<template>
  <el-main>
    <el-row>
      <el-col v-if="parentTreeData.length !== 0" :span="3">
        <el-form>
          <el-form-item>
            <span><b>系统部门列表：</b></span>
          </el-form-item>
          <el-form-item>
            <el-tree
              ref="parentTree"
              highlight-current
              default-expand-all
              :data="parentTreeData"
              :props="parentTreeProps"
              node-key="id"
              class="parentTree"
              @node-click="parentTreeNodeClick"
            />
          </el-form-item>
        </el-form>
      </el-col>
      <el-col :span="parentTreeData.length !== 0 ? 21 : 24">
        <sys-dialog
          :title="sysDialog.title"
          :width="sysDialog.width"
          :height="sysDialog.height"
          :visible="sysDialog.visible"
          @onClose="sysDialogClose"
          @onConfirm="sysDialogConfirm"
        >
          <div slot="content">
            <el-form
              ref="entityForm"
              :model="entityModel"
              :rules="entityRules"
              :inline="true"
              label-width="80px"
            >
              <el-row>
                <el-form-item prop="username" label="用户名称">
                  <el-input v-model="entityModel.username" placeholder="请输入用户名称" />
                </el-form-item>
                <el-form-item prop="password" label="用户密码">
                  <el-input v-model="entityModel.password" placeholder="请输入用户密码" />
                </el-form-item>
                <el-form-item prop="sex" label="用户性别">
                  <el-select v-model="entityModel.sex" placeholder="请输入用户性别">
                    <el-option label="男" :value="0" />
                    <el-option label="女" :value="1" />
                  </el-select>
                </el-form-item>
                <el-form-item prop="phone" label="用户手机">
                  <el-input v-model="entityModel.phone" placeholder="请输入用户手机" />
                </el-form-item>
                <el-form-item prop="email" label="用户邮箱">
                  <el-input v-model="entityModel.email" placeholder="请输入用户邮箱" />
                </el-form-item>
                <el-form-item prop="state" label="用户状态">
                  <el-select v-model="entityModel.state" placeholder="请输入用户状态">
                    <el-option label="账户正常" :value="0" />
                    <el-option label="账户禁用" :value="1" />
                    <el-option label="账户被锁" :value="2" />
                    <el-option label="账户过期" :value="3" />
                    <el-option label="密码过期" :value="4" />
                  </el-select>
                </el-form-item>
                <el-form-item prop="remark" label="用户备注">
                  <el-input v-model="entityModel.remark" placeholder="请输入用户备注" />
                </el-form-item>
                <el-form-item v-if="deptName !== null" prop="deptId" label="所属部门">
                  <el-input v-model="deptName" placeholder="请输入所属部门" readonly />
                </el-form-item>
              </el-row>
            </el-form>
          </div>
        </sys-dialog>
        <el-form
          ref="searchForm"
          :model="searchModel"
          :rules="searchRules"
          :inline="true"
          label-width="80px"
        >
          <el-form-item v-if="checkPermission(['sys:user:search'])" prop="username">
            <el-input v-model="searchModel.username" placeholder="请输入用户名称" />
          </el-form-item>
          <el-form-item>
            <el-button v-if="checkPermission(['sys:user:search'])" icon="el-icon-search" @click="searchHandler()">查询</el-button>
            <el-button v-if="checkPermission(['sys:user:search'])" icon="el-icon-delete" @click="resethHandler()">重置</el-button>
            <el-button v-if="checkPermission(['sys:user:add'])" type="primary" icon="el-icon-plus" @click="addHandler()">新增</el-button>
          </el-form-item>
        </el-form>
        <el-table
          v-loading="loading"
          :data="tableList"
          style="width: 100%;margin-bottom: 18px;"
          row-key="id"
          border
          stripe
          highlight-current-row
          default-expand-all
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        >
          <el-table-column prop="username" label="用户名称" />
          <el-table-column prop="sex" label="用户性别">
            <template slot-scope="scope">
              <span v-if="scope.row.sex === 0">男</span>
              <span v-if="scope.row.sex === 1">女</span>
            </template>
          </el-table-column>
          <el-table-column prop="phone" label="用户手机" />
          <el-table-column prop="email" label="用户邮箱" />
          <el-table-column prop="state" label="用户状态">
            <template slot-scope="scope">
              <el-tag v-if="scope.row.state === 0" type="success">账户正常</el-tag>
              <el-tag v-if="scope.row.state === 1" type="danger">账户禁用</el-tag>
              <el-tag v-if="scope.row.state === 2" type="info">账户被锁</el-tag>
              <el-tag v-if="scope.row.state === 3">账户过期</el-tag>
              <el-tag v-if="scope.row.state === 4" type="warning">密码过期</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="remark" label="用户备注">
            <template slot-scope="scope">
              <span v-if="scope.row.remark === ''">无</span>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" />
          <el-table-column label="操作" align="center" width="360">
            <template slot-scope="scope">
              <el-button v-if="checkPermission(['sys:user:update'])" type="primary" icon="el-icon-edit-outline" @click="updateHandler(scope.row)">编辑</el-button>
              <el-button v-if="checkPermission(['sys:user:delete'])" type="danger" icon="el-icon-close" @click="deleteHandler(scope.row)">删除</el-button>
              <el-button v-if="checkPermission(['sys:user:assign'])" type="success" icon="el-icon-share" @click="assignHandler(scope.row)">分配角色</el-button>
            </template>
          </el-table-column>
        </el-table>
        <pagination
          v-show="tableTotal>0"
          :total="tableTotal"
          :page.sync="searchModel.pageNum"
          :limit.sync="searchModel.pageSize"
          @pagination="fetchList"
        />
      </el-col>
    </el-row>
    <sys-dialog
      :title="sysRoleDialog.title"
      :width="sysRoleDialog.width"
      :height="sysRoleDialog.height"
      :visible="sysRoleDialog.visible"
      @onClose="sysRoleDialogClose"
      @onConfirm="sysRoleDialogConfirm"
    >
      <div slot="content">
        <el-table
          ref="roleTable"
          style="width: 100%;margin-bottom: 14px;"
          :data="roleTableList"
          row-key="id"
          border
          stripe
          highlight-current-row
          @select="roleTableSelectHandler"
          @select-all="roleTableSelectAllHandler"
        >
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column prop="name" label="角色名称" />
          <el-table-column prop="createTime" label="创建时间" />
        </el-table>
        <div style="text-align:center">
          <pagination
            v-show="roleTableTotal>0 && roleSearchPages>1"
            :layout="'prev, pager, next'"
            :total="roleTableTotal"
            :page.sync="roleSearchModel.pageNum"
            :limit.sync="roleSearchModel.pageSize"
            @pagination="fetchRoleList"
          />
        </div>
      </div>
    </sys-dialog>
  </el-main>
</template>

<script>
import checkPermission from '@/utils/permission'
import { add, deleteById, update, getById, getPage, getRole, assignRole } from '@/api/sysUser'
import { getList, getById as getDeptById } from '@/api/sysDepartment'
import { getPage as getRolePage } from '@/api/sysRole'
import Pagination from '@/components/Pagination'
import SysDialog from '@/components/SysDialog'
import { validUsername, validPassword, validPhone, validEmail } from '@/utils/validate'
export default {
  name: 'SysUser',
  components: {
    Pagination,
    SysDialog
  },
  props: {},
  data() {
    const validateUsername = (rule, value, callback) => {
      if (!validUsername(value)) {
        callback(new Error('2-10位，可字母、中文、下划线'))
      } else {
        callback()
      }
    }
    const validatePassword = (rule, value, callback) => {
      if (!validPassword(value)) {
        callback(new Error('4-20位，可字母、数字、下划线'))
      } else {
        callback()
      }
    }
    const validatePhone = (rule, value, callback) => {
      if (!validPhone(value)) {
        callback(new Error('请输入正确的手机号'))
      } else {
        callback()
      }
    }
    const validateEmail = (rule, value, callback) => {
      if (!validEmail(value)) {
        callback(new Error('请输入正确的邮箱号'))
      } else {
        callback()
      }
    }
    return {
      loading: false,
      tableList: [],
      tableTotal: 0,
      sysDialog: {
        title: '系统提示',
        type: 'add',
        visible: false,
        width: 590,
        height: 250
      },
      entityModel: {
        id: null,
        username: null,
        password: null,
        sex: 0,
        phone: null,
        email: null,
        state: 0,
        remark: null,
        createTime: null,
        deptId: null
      },
      entityRules: {
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }],
        phone: [{ required: true, trigger: 'blur', validator: validatePhone }],
        email: [{ required: true, trigger: 'blur', validator: validateEmail }]
      },
      searchModel: {
        name: null,
        deptId: null,
        pageNum: 1,
        pageSize: 10
      },
      searchRules: {
        username: [{ required: true, trigger: 'blur', message: '请输入用户名称' }]
      },
      parentTreeData: [],
      parentTreeProps: {
        label: 'name',
        children: 'children'
      },
      parentTreeCheckedId: null,
      deptName: null,
      sysRoleDialog: {
        title: '系统提示',
        type: 'assign',
        visible: false,
        width: 590,
        height: 400
      },
      roleTableList: [],
      roleTableTotal: 0,
      roleSearchPages: 0,
      roleSearchModel: {
        pageNum: 1,
        pageSize: 7
      },
      userCheckedId: null,
      roleCheckedPageNum: 1,
      roleCheckedPageArr: []
    }
  },
  created() {
    // 获取系统部门列表
    this.loadDeptTree()
    // 获取系统用户列表
    this.fetchList()
  },
  mounted() {},
  methods: {
    checkPermission,
    fetchList(data) {
      this.loading = true
      // 分页信息改变
      if (data !== undefined) {
        this.searchModel.pageNum = data.page
        this.searchModel.pageSize = data.limit
      }
      // 分页获取列表
      getPage(this.searchModel).then(response => {
        if (response.code === 200) {
          this.tableList = response.data.list
          this.tableTotal = response.data.total
          this.searchModel.pageNum = response.data.pageNum
          this.searchModel.pageSize = response.data.pageSize
          this.loading = false
        }
      })
    },
    sysDialogOpen(title, type) {
      // 设置窗口属性
      this.sysDialog.title = title
      this.sysDialog.type = type
      this.sysDialog.visible = true
      // 重置表单内容
      this.$nextTick(() => {
        this.$refs.entityForm.resetFields()
        // 加载部门名称
        if (type === 'add') {
          this.entityModel.id = null
          this.entityModel.deptId = this.parentTreeCheckedId
          this.loadDeptName()
        }
      })
    },
    sysDialogClose() {
      this.sysDialog.visible = false
      this.entityModel.deptId = this.parentTreeCheckedId
    },
    sysDialogConfirm() {
      this.$refs.entityForm.validate(valid => {
        if (valid) {
          if (this.sysDialog.type === 'add') {
            add(this.entityModel).then(response => {
              if (response.code === 200) {
                this.$notify.success({ title: '系统提示', message: response.msg })
                this.fetchList()
                this.sysDialogClose()
              }
            })
          }
          if (this.sysDialog.type === 'update') {
            update(this.entityModel).then(response => {
              if (response.code === 200) {
                this.$notify.success({ title: '系统提示', message: response.msg })
                this.fetchList()
                this.sysDialogClose()
              }
            })
          }
        }
      })
    },
    parentTreeNodeClick(data) {
      this.parentTreeCheckedId = data.id
      this.searchModel.deptId = data.id
      this.fetchList()
    },
    loadDeptTree() {
      getList().then(response => {
        if (response.code === 200) {
          this.parentTreeData = response.data
        }
      })
    },
    loadDeptName() {
      getDeptById({ 'id': this.entityModel.deptId }).then((response) => {
        if (response.code === 200) {
          if (response.data) {
            this.deptName = response.data.name
          }
        }
      })
    },
    searchHandler() {
      this.$refs.searchForm.validate(valid => {
        if (valid) {
          this.$refs.parentTree.setCurrentKey(null)
          this.parentTreeCheckedId = null
          this.searchModel.pageNum = 1
          this.searchModel.deptId = null
          this.fetchList()
        }
      })
    },
    resethHandler() {
      this.$refs.searchForm.resetFields()
      this.$refs.parentTree.setCurrentKey(null)
      this.parentTreeCheckedId = null
      this.searchModel.pageNum = 1
      this.searchModel.pageSize = 10
      this.searchModel.deptId = null
      this.fetchList()
    },
    addHandler() {
      this.sysDialogOpen('新增系统用户', 'add')
    },
    updateHandler(row) {
      this.sysDialogOpen('修改系统用户', 'update')
      getById({ id: row.id }).then(response => {
        if (response.code === 200) {
          this.entityModel = response.data
          // 加载部门名称
          this.loadDeptName()
        }
      })
    },
    deleteHandler(row) {
      this.$confirm('此操作将永久删除该记录及角色映射记录，是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteById({ id: row.id }).then(response => {
          if (response.code === 200) {
            this.$notify.success({ title: '系统提示', message: response.msg })
            this.fetchList()
          }
        })
      }).catch(() => {})
    },
    fetchRoleList(data) {
      // 分页信息改变
      if (data !== undefined) {
        this.roleSearchModel.pageNum = data.page
        this.roleSearchModel.pageSize = data.limit
      }
      // 获取角色分页
      getRolePage(this.roleSearchModel).then((response) => {
        if (response.code === 200) {
          this.roleTableList = response.data.list
          this.roleTableTotal = response.data.total
          this.roleSearchPages = response.data.pages
          // 获取角色对象
          getRole({ 'id': this.userCheckedId, 'pageSize': this.roleSearchModel.pageSize }).then((response) => {
            if (response.code === 200 && this.roleCheckedPageArr.length === 0) {
              this.roleCheckedPageArr = response.data.checks
            }
            // 回显本页数据
            this.roleTableList.forEach((item) => {
              const hasRole = this.roleCheckedPageArr[this.roleSearchModel.pageNum - 1].indexOf(item.id)
              if (hasRole !== -1) {
                this.$refs.roleTable.toggleRowSelection(item, true)
              }
            })
          })
        }
      })
    },
    assignHandler(row) {
      // 设置分配用户
      this.userCheckedId = row.id
      // 设置窗口属性
      this.sysRoleDialog.title = `为【 ${row.username} 】分配角色`
      this.sysRoleDialog.visible = true
      // 重置查询参数
      this.roleSearchModel.pageNum = 1
      // 加载角色列表
      this.fetchRoleList()
    },
    sysRoleDialogClose() {
      // 设置窗口属性
      this.sysRoleDialog.title = null
      this.sysRoleDialog.visible = false
      // 清空当前选中
      this.$nextTick(() => {
        this.$refs.roleTable.clearSelection()
      })
      this.roleCheckedPageArr = []
    },
    sysRoleDialogConfirm() {
      // 判断是否选择
      let rids = []
      for (let index = 0; index < this.roleCheckedPageArr.length; index++) {
        rids = rids.concat(this.roleCheckedPageArr[index])
      }
      if (rids.length === 0) {
        this.$alert('请在系统角色列表中选择相应的角色！', '温馨提示', {
          confirmButtonText: '确定',
          type: 'warning'
        })
        return
      }
      // 保存分配结果
      assignRole({ 'uid': this.userCheckedId, 'rids': rids }).then((response) => {
        if (response.code === 200) {
          this.$notify.success({ title: '系统提示', message: response.msg })
          this.sysRoleDialogClose()
        }
      })
    },
    roleTableSelectHandler(selection) {
      this.roleCheckedPageArr[this.roleSearchModel.pageNum - 1] = selection.map((item) => item.id)
    },
    roleTableSelectAllHandler(selection) {
      this.roleCheckedPageArr[this.roleSearchModel.pageNum - 1] = selection.map((item) => item.id)
    }
  }
}
</script>

<style lang="scss" scoped>
.parentTree {
  overflow: hidden;
  margin-right: 20px;
  border-radius: 4px;
  border: 1px solid #DCDFE6;
}
.pagination-container {
  margin: 0;
  padding: 0;
}
</style>
